package com.pandas.community.Utils;

import org.apache.commons.lang3.CharUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

@Component
public class SensitiveFilter {
    private static final Logger logger = LoggerFactory.getLogger(SensitiveFilter.class);

    //替换词
    private static final String REPLACEMENT = "***";

    private TrieNode root = new TrieNode();

    @PostConstruct
    public void init(){
        try(
            InputStream is = this.getClass().getClassLoader().getResourceAsStream("敏感词.txt");
            BufferedReader reader = new BufferedReader(new InputStreamReader(is))
            ){
            String word = null;
            while((word = reader.readLine()) != null){
                this.addWord(word);
            }
        }catch (IOException e){
            logger.error("读取敏感词失败"+e.getMessage());
        }
    }

    // 构建前缀树
    private void addWord(String word){
        TrieNode temp = root;
        for(int i = 0; i < word.length(); i++){
            char c = word.charAt(i);
            if(temp.getSubNode(c) == null){
                temp.addSubNode(c, new TrieNode());
            }

            temp = temp.getSubNode(c);
            if(i == word.length() - 1){
                temp.setWordEnd(true);
            }
        }
    }

    private class TrieNode{
        private boolean isEnd = false;
        private Map<Character, TrieNode> subNodes = new HashMap<>();

        public boolean isWordEnd(){
            return isEnd;
        }

        public void setWordEnd(boolean isEnd){
            this.isEnd = isEnd;
        }

        public void addSubNode(Character c, TrieNode node){
            subNodes.put(c, node);
        }

        public TrieNode getSubNode(Character c){
            return subNodes.get(c);
        }
    }

    public String filter(String text){
        if(StringUtils.isBlank(text)) return null;

        TrieNode temp = root;
        StringBuilder builder = new StringBuilder();

        int begin = 0, index = 0;
        while(index < text.length()){
            char c = text.charAt(index);
            // 跳过字符
            if(isSymbol(c)){
                // 如果起始位置为符号， 过滤的起点往后移 ☆word☆☆word☆☆☆
                if(temp == root){
                    begin++;
                    builder.append(c);
                }
                index++;
                continue;
            }

            temp = temp.getSubNode(c);
            if(temp == null){
                builder.append(text.charAt(begin));
                index = ++begin;
                temp = root;
            }else if(temp.isWordEnd()){
                // begin开头， index结尾是敏感词
                builder.append(REPLACEMENT);
                begin = ++index;
                temp = root;
            }else{
                index++;
            }
        }

        builder.append(text.substring(begin));
        return builder.toString();
    }

    private boolean isSymbol(Character c){
        // c < 0x2E80 || c > 0x9FFF 东亚文字范围
        return !CharUtils.isAsciiAlphanumeric(c) && (c < 0x2E80 || c > 0x9FFF);
    }

}
